/*******************************************************************************
 * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
 * @file     transport.c
 * @author   UartTFT Application Team
 * @version  V0.0.1
 * @date     2023-01-01
 * @brief
 ********************************************************************************/

#include "transport.h"
#include "delay.h"
#include "data.h"
#include "w25qxx.h"
#include "w25n01.h"
#include "tftlcd.h"
#include "module_select.h"


/********************************************************************************
* Function Name	: LT_ReadFlash
* Description  	: Read data from external FLASH.
* Input        	: - *pBuffer: buffer for read data
				  - ReadAddr: Address to start reading
				  - NumByteToRead: Number of bytes to read
* Output       	: None
* Return       	: None
*********************************************************************************/
void LT_ReadFlash(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
	if (Flash_Type != 2)
	{
		// NorFlash_Read(pBuffer, ReadAddr, NumByteToRead);	//STD
		NorFlash_Read(pBuffer, ReadAddr, NumByteToRead); 	//DUAL
	}
	else
	{
		uint16_t page, column, pageremain;

		page = (ReadAddr / 2048);
		column = (ReadAddr % 2048);
		pageremain = 2048 - column;
		// printf("page column pageremain %d   %d %d \r\n",page,column,pageremain);

		if (NumByteToRead <= pageremain)
			pageremain = NumByteToRead;
		for (;;)
		{
			NandFlash_Read(page, column, pBuffer, pageremain);
			if (NumByteToRead == pageremain)
				break;
			else
			{
				pBuffer += pageremain;
				page++;
				column = 0;
				NumByteToRead -= pageremain;
				if (NumByteToRead > 2048)
					pageremain = 2048;
				else
					pageremain = NumByteToRead;
			}
		}
	}

	DelayUS(1); // wav need
}

/********************************************************************************
* Function Name	: LT_ReadFlash_DMA
* Description  	: Read data from external FLASH.
* Input        	: - *pBuffer: buffer for read data
				  - ReadAddr: Address to start reading
				  - NumByteToRead: Number of bytes to read
* Output       	: None
* Return       	: None
*********************************************************************************/
void LT_ReadFlash_DMA(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
	if (Flash_Type != 2)
	{
		uint32_t dma_len = DMA_LEN3;

		if (NumByteToRead <= dma_len)
			dma_len = NumByteToRead;
		for (;;)
		{
			NorFlash_DMA_Read(pBuffer, ReadAddr, dma_len); //DUAL DMA
			NorFlash_DMA_Wait();
			//DelayUS(1); // wav need

			if (NumByteToRead == dma_len)
				break;
			else
			{
				pBuffer += dma_len;
				ReadAddr += dma_len;
				NumByteToRead -= dma_len;
				if (NumByteToRead > DMA_LEN3)
					dma_len = DMA_LEN3;
				else
					dma_len = NumByteToRead;
			}
		}
	}
	else
	{
		uint16_t page, column, pageremain;

		page = (ReadAddr / 2048);
		column = (ReadAddr % 2048);
		pageremain = 2048 - column;
		// printf("page column pageremain %d   %d %d \r\n",page,column,pageremain);

		if (NumByteToRead <= pageremain)
			pageremain = NumByteToRead;
		for (;;)
		{
			NandFlash_DMA_Read(page, column, pBuffer, pageremain);
			NandFlash_DMA_Wait();
			if (NumByteToRead == pageremain)
				break;
			else
			{
				pBuffer += pageremain;
				page++;
				column = 0;

				NumByteToRead -= pageremain;
				if (NumByteToRead > 2048)
					pageremain = 2048;
				else
					pageremain = NumByteToRead;
			}
		}
	}

	DelayUS(1); // wav need
}

/********************************************************************************
* Function Name	: TFT_Data_Tran
* Description  	: Write array data to TFT continuously.
* Input        	: - *Tx_Addr: data buffer(RGB565,MSB first)
				  - length: Number of bytes to write(even number)
* Output       	: None
* Return       	: None
*********************************************************************************/
void TFT_Data_Tran(uint8_t *Tx_Addr, uint32_t length)
{
#if (LT_TFT_PORT == 0)

	if (length == 0)
		return;

	uint32_t i;
	uint16_t *Data = (uint16_t *)Tx_Addr;

	for (i = 0; i < length / 2; i++)
	{
		Data[i] = ((Data[i] >> 8) | (Data[i] << 8));
	}

	LCD_SPI_WriteData_DMA(Tx_Addr, length);

#endif

#if (LT_TFT_PORT == 1 || LT_TFT_PORT == 2)
	uint32_t m = 0;
	volatile uint8_t valHigh, valLow;

	valHigh = LCD_WR_READ_H;
	valLow = LCD_WR_READ_L;

	for (m = 1; m <= length / 2; m++)
	{
#if (LT_TFT_PORT == 1)
		LCD_DATA_WRITE_L = Tx_Addr[2 * m - 1];
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
		LCD_DATA_WRITE_L = Tx_Addr[2 * m - 2];
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
#endif
#if (LT_TFT_PORT == 2)
		LCD_DATA_WRITE_H = Tx_Addr[2 * m - 1];
		LCD_DATA_WRITE_L = Tx_Addr[2 * m - 2];
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
#endif
	}
#endif
}


/********************************************************************************
* Function Name	: TFT_Data_Tran
* Description  	: Write the same color to TFT continuously.
* Input        	: - *Tx_Addr: data buffer(RGB565,MSB first)
				  - length: Number of bytes to write
* Output       	: None
* Return       	: None
*********************************************************************************/
void TFT_Data_Tran2(uint16_t Tx_Addr, uint32_t length)
{
#if (LT_TFT_PORT == 0)
	uint32_t i;

	for (i = 0; i < length; i++)
	{
		LCD_SPI_ReadWriteByte(Tx_Addr >> 8);
		//		__ASM("nop");	__ASM("nop"); __ASM("nop"); __ASM("nop");
		LCD_SPI_ReadWriteByte(Tx_Addr);
		//		__ASM("nop");	__ASM("nop"); __ASM("nop"); __ASM("nop");
	}
#endif

#if (LT_TFT_PORT == 1 || LT_TFT_PORT == 2)
	uint32_t m = 0;
	volatile uint8_t valHigh, valLow;

	valHigh = LCD_WR_READ_H;
	valLow = LCD_WR_READ_L;

	for (m = 0; m < length; m++)
	{
#if (LT_TFT_PORT == 1)
		LCD_DATA_WRITE_L = Tx_Addr >> 8;
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
		LCD_DATA_WRITE_L = Tx_Addr;
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
#endif
#if (LT_TFT_PORT == 2)
		LCD_DATA_WRITE_H = Tx_Addr >> 8;
		LCD_DATA_WRITE_L = Tx_Addr;
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
#endif
	}
#endif
}

/********************************************************************************
* Function Name	: TFT_Data_Tran
* Description  	: Write array data to TFT continuously.
* Input        	: - *Tx_Addr: data buffer(RGB565,MSB first)
				  - length: Number of bytes to write
* Output       	: None
* Return       	: None
*********************************************************************************/
void TFT_Data_Tran3(uint16_t *Tx_Addr, uint32_t length)
{
#if (LT_TFT_PORT == 0)

	if (length == 0)
		return;

	length = length * 2;

	LCD_SPI_WriteData_DMA((uint8_t *)Tx_Addr, length);

#endif

#if (LT_TFT_PORT == 1 || LT_TFT_PORT == 2)
	uint32_t m = 0;
	volatile uint8_t valHigh, valLow;

	valHigh = LCD_WR_READ_H;
	valLow = LCD_WR_READ_L;

	for (m = 0; m < length; m++)
	{
#if (LT_TFT_PORT == 1)
		LCD_DATA_WRITE_L = Tx_Addr[m] >> 8;
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
		LCD_DATA_WRITE_L = Tx_Addr[m];
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
#endif
#if (LT_TFT_PORT == 2)
		LCD_DATA_WRITE_H = Tx_Addr[m] >> 8;
		LCD_DATA_WRITE_L = Tx_Addr[m];
		LCD_WR_WRITE = valLow;
		LCD_WR_WRITE = valHigh;
#endif
	}
#endif
}

#if 0
void TFT_Data_Tran_nand(uint8_t* Tx_Addr, uint32_t length)
{
#if (LT_TFT_PORT == 0) 
	
	if(length==0) return;
	
	uint32_t i;
	uint16_t *Data = (uint16_t*)Tx_Addr;
	
	for(i=0;i<length/2;i++)
	{
		Data[i] = ((Data[i]>>8) | (Data[i]<<8));
	}
	
	LCD_SPI_WriteData_DMA(Tx_Addr,length); 

	if(length%2) 
	{
		LCD_SPI_WriteData_DMA(&Tx_Addr[length-1],length); 
	}
#endif

#if (LT_TFT_PORT == 1 || LT_TFT_PORT == 2) 
	uint32_t  m=0;
	volatile uint8_t valHigh,valLow;
	
	valHigh = LCD_WR_READ_H; 
	valLow  = LCD_WR_READ_L;
	
	for(m=0;m<length/2;m++)
	{
#if (LT_TFT_PORT == 1) 
			LCD_DATA_WRITE_L = Tx_Addr[2*m+1];
			LCD_WR_WRITE = valLow; 
			LCD_WR_WRITE = valHigh;	
			LCD_DATA_WRITE_L = Tx_Addr[2*m];
			LCD_WR_WRITE = valLow; 	
			LCD_WR_WRITE = valHigh;
#endif
#if (LT_TFT_PORT == 2) 
			LCD_DATA_WRITE_H = Tx_Addr[2*m+1];
			LCD_DATA_WRITE_L = Tx_Addr[2*m];
			LCD_WR_WRITE = valLow; 			   
			LCD_WR_WRITE = valHigh;
#endif
	}
	
	if(length%2) 
	{
			LCD_DATA_WRITE_L = Tx_Addr[2*m];
			LCD_WR_WRITE = valLow; 	
			LCD_WR_WRITE = valHigh;	
	}

#endif
}
#endif

//----------------------------------------------------------------------------------
